/* $RCSFile: AddonNiceProfileProvider.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Authentication/AddonNiceProfileProvider.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:26  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System.Web.Services.Protocols;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Net;
using System.Collections;
using System.Web.Profile;
using System.Globalization;

using AddonNice.Settings;
using AddonNice.Configuration;
using AddonNice.Security;
using AddonNice.CRMWrapper;

namespace AddonNice.Authentication
{

	public sealed class AddonNiceProfileProvider : ProfileProvider
	{
		CRMWrapperBase Wrapper = PortalSecurity.Wrapper;

		// Global connection string
		private string connectionString;


		/// <summary>
		/// ApplicationName is PortalName
		/// </summary>
		string	_DefAppName	            =	string.Empty;
		public override string ApplicationName
		{
			get 
            { 
                string _AppName         =   string.Empty;
				PortalSettings p        =   (PortalSettings)HttpContext.Current.Items[StStr.strPortalSettings];
                if ( p != null )
					 _AppName           =   p.BaseAlias;
                else _AppName           =   _DefAppName;
                return _AppName; 
            }
			set { _DefAppName = value; }
		}

		int _DefPortalID            =   0;
		public int PortalID
		{
			get 
			{
                int _PortalID       =   _DefPortalID;
				PortalSettings p    =   (PortalSettings)HttpContext.Current.Items[StStr.strPortalSettings];
                if ( p != null )
				    _PortalID       =   p.PortalID;
				return _PortalID; 
			}
            set
            {
                _DefPortalID            =  value;
            }
		}


		/// <summary>
		/// GetPropertyValues
		/// </summary>
		/// <param name="name"></param>
		/// <param name="config"></param>
		public override void Initialize(string name, NameValueCollection config)
		{
            if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]AddonNiceProfileProvider Initialize BEG.",SecurityTraceSwitch.Sw.Info);
			// Initialize values from web.config.
			if (config == null)
				throw new ArgumentNullException("config");

			if ( string.IsNullOrEmpty(name) )
				name                =   "AddonNiceProfileProvider";

			if (String.IsNullOrEmpty(config["description"]))
			{
				config.Remove("description");
				config.Add("description", "Addon Nice CRM Profile provider");
			}

			// Initialize the abstract base class.
			base.Initialize(name, config);


			if ( !string.IsNullOrEmpty(config["applicationName"]))
			{
				_DefAppName         =   config["applicationName"];
			}

			ConnectionStringSettings pConnectionStringSettings  =   ConfigurationManager.ConnectionStrings[config["connectionStringName"]];

			// if as specific connexion string has been defined take it, else take std connexion string from config
			if ( pConnectionStringSettings == null )
				connectionString    =   pConnectionStringSettings.ConnectionString;
			else connectionString   =   Config.ConnectionString;
            if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]AddonNiceProfileProvider Initialize END.",SecurityTraceSwitch.Sw.Info);
		}





		/// <summary>
		/// 
		/// </summary>
		public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection ppc)
		{
            if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]AddonNiceProfileProvider GetPropertyValues BEG.",SecurityTraceSwitch.Sw.Info);
			string username				=   (string)context["UserName"];
			bool isAuthenticated		=   (bool)context["IsAuthenticated"];
			
            SettingsPropertyValueCollection svc = new SettingsPropertyValueCollection();

            DynEntity dynEnt	        =   GetCrmCustomerId(username);
            if (dynEnt == null)
            {
                return svc;
            }

            if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider GetPropertyValues begin portalID: {0}, CrmCustomerId: {1}, isAuthenticated: {2} ", 
                    new object[] { PortalID, dynEnt.PrimaryKeyGuidValue, isAuthenticated }),SecurityTraceSwitch.Sw.Info);

            foreach (SettingsProperty prop in ppc)
			{
				SettingsPropertyValue pv    =  new SettingsPropertyValue(prop);

				switch (prop.Name)
				{
					case "typeCode":
						pv.PropertyValue    =  GetTypeCode(dynEnt, isAuthenticated);
                        break;
					case "CrmImpersonateId":
						pv.PropertyValue    =  GetCrmImpersonateId(dynEnt, isAuthenticated);
						break;
					case "ProfileIsAnonymous":
						pv.PropertyValue    =  GetIsAnonymous(dynEnt, isAuthenticated);
						break;
					case "ProfileIsDesactivated":
						pv.PropertyValue    =  GetIsDesactivated(dynEnt, isAuthenticated);
						break;
					case "ProfileIsValidated":
						pv.PropertyValue    =  GetIsValidated(dynEnt, isAuthenticated);
						break;
                    case "EMail":
						pv.PropertyValue    =   GetEMail(dynEnt, isAuthenticated);
						break;
                    case "CrmId":
						pv.PropertyValue    =   GetCrmId(dynEnt, isAuthenticated);
						break;
                    case "BillingCountry":
						pv.PropertyValue    =   GetBillingCountry(dynEnt, isAuthenticated);
						break;
					default:
						throw new ProviderException("Unsupported property.");
				}
                if ( SecurityTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider GetPropertyValues adding: {0}, value: {1}",prop.Name,pv.PropertyValue ),SecurityTraceSwitch.Sw.Info);
				svc.Add(pv);
			}
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider GetPropertyValues end portalID: {0}, CrmCustomerId: {1}, isAuthenticated: {2} ", 
                    new object[] { PortalID, dynEnt.PrimaryKeyGuidValue, isAuthenticated }),SecurityTraceSwitch.Sw.Info);
			UpdateActivityDates(PortalID,dynEnt.PrimaryKeyGuidValue,isAuthenticated, true);
			return svc;
		}


        //TODO read in DB/CRM for all accessors
		string GetEMail(DynEntity dynEnt,bool isAuthenticated)
		{
            if ( dynEnt.ContainsKey(CrmStr.email))
			    return  dynEnt.StringPropertyValue(CrmStr.email);
            return string.Empty;
		}
        
		string GetBillingCountry(DynEntity dynEnt,bool isAuthenticated)
		{
            if ( dynEnt.ContainsKey(CrmStr.address1_country))
			    return  dynEnt.StringPropertyValue(CrmStr.address1_country);
            return string.Empty;
		}

        int GetTypeCode(DynEntity dynEnt, bool isAuthenticated)
        {
            return 2;  // contact
        }

        Guid GetCrmId(DynEntity dynEnt,bool isAuthenticated)
		{
			return dynEnt.PrimaryKeyGuidValue;
		}

        Guid GetCrmImpersonateId(DynEntity dynEnt,bool isAuthenticated)
		{
			return Wrapper.userId;
		}
		bool GetIsAnonymous(DynEntity dynEnt,bool isAuthenticated)
		{
			return false;
		}
		bool GetIsDesactivated(DynEntity dynEnt,bool isAuthenticated)
		{
			return false;
		}
		bool GetIsValidated(DynEntity dynEnt,bool isAuthenticated)
		{
			return true;
		}


		//
		// SettingsProvider.SetPropertyValues
		//

		public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection ppvc)
		{
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine("[V]AddonNiceProfileProvider SetPropertyValues BEG .",SecurityTraceSwitch.Sw.Info);
			// The serializeAs attribute is ignored in this provider implementation.
			string username			=   (string)context["UserName"];
			bool isAuthenticated	=   (bool)context["IsAuthenticated"];
			DynEntity dynEnt		=   GetCrmCustomerId(username);
			if (dynEnt == null)
                return;
				//CrmCustomerId		=   CreateProfileForUser(username,isAuthenticated);

			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider SetPropertyValues portalID: {0}, CrmCustomerId: {1}, isAuthenticated: {2} ", 
                    new object[] { PortalID, dynEnt.PrimaryKeyGuidValue, isAuthenticated }),SecurityTraceSwitch.Sw.Info);
			
			foreach (SettingsPropertyValue pv in ppvc)
			{
				switch (pv.Property.Name)
				{
					case "typeCode":
						SetTypeCode(dynEnt, (int)pv.PropertyValue);
						break;
					case "CrmImpersonateId":
						SetCrmImpersonateId(dynEnt, (Guid)pv.PropertyValue);
						break;
					case "ProfileIsAnonymous":
						SetIsAnonymous(dynEnt, (bool)pv.PropertyValue);
						break;
					case "ProfileIsDesactivated":
						SetIsDesactivated(dynEnt, (bool)pv.PropertyValue);
						break;
					case "ProfileIsValidated":
						SetIsValidated(dynEnt, (bool)pv.PropertyValue);
						break;
                    case "EMail":
						SetEMail(dynEnt, (string)pv.PropertyValue);
						break;
                    case "CrmId":
						SetCrmId(dynEnt, (Guid)pv.PropertyValue);
						break;
                    case "BillingCountry":
						SetBillingCountry(dynEnt,(string)pv.PropertyValue);
						break;
					default:
						throw new ProviderException("Unsupported property.");
				}
			}

			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider SetPropertyValues END portalID: {0}, CrmCustomerId: {1}, isAuthenticated: {2} ", 
                    new object[] { PortalID, dynEnt.PrimaryKeyGuidValue, isAuthenticated }),SecurityTraceSwitch.Sw.Info);
			UpdateActivityDates(PortalID, dynEnt.PrimaryKeyGuidValue, isAuthenticated, false);
		}

        void SetTypeCode(DynEntity dynEnt, int val)
		{}
        void SetEMail(DynEntity dynEnt, string Email)
		{}
        void SetCrmId(DynEntity dynEnt, Guid CrmId)
		{}
        void SetBillingCountry(DynEntity dynEnt,string BillingCountry)
		{}
        void SetCrmImpersonateId(DynEntity dynEnt, Guid CrmImpersonateId)
		{}
		void SetIsAnonymous(DynEntity dynEnt,bool val)
		{}
		void SetIsDesactivated(DynEntity dynEnt,bool val)
		{}
		void SetIsValidated(DynEntity dynEnt,bool val)
		{}

		//
		// UpdateActivityDates
		// Updates the LastActivityDate and LastUpdatedDate values 
		// when profile properties are accessed by the
		// GetPropertyValues and SetPropertyValues methods. 
		// Passing true as the activityOnly parameter will update
		// only the LastActivityDate.
		//

		private void UpdateActivityDates(int portalID, Guid CrmCustomerId, bool isAuthenticated, bool activityOnly)
		{
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider UpdateActivityDates begin portalID: {0}, CrmCustomerId: {1}, activityOnly: {2} ", 
                    new object[] { portalID, CrmCustomerId, activityOnly }),SecurityTraceSwitch.Sw.Info);

			SqlConnection conn = new SqlConnection(connectionString);
			SqlCommand cmd = new SqlCommand();
			cmd.CommandType = CommandType.StoredProcedure;
			cmd.Connection = conn;

			if (activityOnly)
			{
				cmd.CommandText = "dbo.adn_UpdateAddonNiceProfileActivity";
				cmd.Parameters.Add("@PortalID", SqlDbType.Int).Value = portalID;
				//cmd.Parameters.Add("@CrmTypeCode", SqlDbType.Int).Value = typeCode;
				cmd.Parameters.Add("@CrmCustomerId", SqlDbType.UniqueIdentifier).Value = CrmCustomerId;
			}
			else
			{
				cmd.CommandText = "dbo.adn_UpdateAddonNiceProfileActivity2";
				cmd.Parameters.Add("@PortalID", SqlDbType.Int).Value = portalID;
				//cmd.Parameters.Add("@CrmTypeCode", SqlDbType.Int).Value = typeCode;
				cmd.Parameters.Add("@CrmCustomerId", SqlDbType.UniqueIdentifier).Value = CrmCustomerId;
			}

			try
			{
				conn.Open();
				cmd.ExecuteNonQuery();
			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider UpdateActivityDates  portalID: {0}, CrmCustomerId: {1}, ex: {2}",
                        new object[] { portalID, CrmCustomerId, ex }),SecurityTraceSwitch.Sw.Info);
				throw new CRMWrapperException("GetCrmCustomerId Sx", ex);
			}
			finally
			{
				conn.Close();
			}
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider UpdateActivityDates end portalID: {0}, CrmCustomerId: {1} ", 
                    new object[] { portalID, CrmCustomerId }),SecurityTraceSwitch.Sw.Info);
		}



		/// <summary>
		/// Request CRM server to extract the Guid from CRM using name 
		/// </summary>
		private DynEntity GetCrmCustomerId(string username)
		{
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider GetCrmCustomerId begin portalID: {0}, username: {1} ", 
                    new object[] { PortalID, username }),SecurityTraceSwitch.Sw.Info);
			DynEntity dynEnt                    =   null;
			try
			{
                bool created                    =   false;/*
				switch (typeCode)
				{
					case (int)ADNTypeCodes.Account:
                        dynEnt                  =   Wrapper.Util.FindAccountByName(username,false,ref created);
						break;
					case (int)ADNTypeCodes.Lead:
                        dynEnt                  =   Wrapper.Util.FindLeadByName(username,false,ref created);
						break;
					case (int)ADNTypeCodes.Contact:*/
                        dynEnt                  =   Wrapper.Util.FindContactByName(username,false,ref created);
						/*
                         * break;
					default:
						{
                            string msg  =   string.Format("[E]AddonNiceProfileProvider GetCrmCustomerId unknown typeCode throwing exception portalID: {0}, typeCode: {1},username: {2} ", new object[] { PortalID, typeCode, username });
							if ( SecurityTraceSwitch.Sw.TraceError )
                                Trace.WriteLine(msg,SecurityTraceSwitch.Sw.Info);
							throw new Exception(msg);
						}
				}*/
			}

			catch (SoapException sx)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceProfileProvider GetCrmCustomerId  ex : {0}-{1}", sx, sx.Detail.InnerText),SecurityTraceSwitch.Sw.Info);
				throw new CRMWrapperException("GetCrmCustomerId Sx", sx);
			}
			catch (CRMWrapperException)
			{
				throw;
			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceProfileProvider GetCrmCustomerId ex : {0}", ex),SecurityTraceSwitch.Sw.Info);
				throw new CRMWrapperException("GetCrmCustomerId Sx", ex);
			}
			if ( SecurityTraceSwitch.Sw.TraceError )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceProfileProvider GetCrmCustomerId UserName : {0}, CrmCustomerId null", username),SecurityTraceSwitch.Sw.Info);
			return dynEnt;
		}


		//
		// CreateProfileForUser
		// If no user currently exists in the database, 
		// a user record is created during
		// the call to the GetCrmCustomerId private method.
		//
		private Guid CreateProfileForUser(string username, bool isAuthenticated)
		{
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider CreateProfileForUser begin portalID: {0}, username: {1} ", new object[] { PortalID, username }),SecurityTraceSwitch.Sw.Info);
			// Check for valid user name.
			if (string.IsNullOrEmpty(username))
				throw new ArgumentNullException("User name cannot be null.");
			if (username.Length > 255)
				throw new ArgumentException("User name exceeds 255 characters.");
			if (username.IndexOf(",") > 0)
				throw new ArgumentException("User name cannot contain a comma (,).");
			Guid CrmCustomerId			=   Guid.Empty;
			DynEntity im				=   null;

            Guid ImpersonateGuid	    =	Wrapper.userId;
			bool isAnonymous		    =	string.IsNullOrEmpty(username);
			string	salt			    = 	string.Empty;
			string	suserMail		    =	string.Empty;
			// Create in CRM using web service
			try
			{
				CrmCustomerId			= im.adminCreate();
				if ( SecurityTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider CreateProfileForUser CrmCustomerId :{0}", CrmCustomerId),SecurityTraceSwitch.Sw.Info);
				// try to add new user in DB
				//new AddonNiceUserDB().AddAddonNiceProfile(PortalID,2, CrmCustomerId,ImpersonateGuid,username, Question, Answer,Password,salt,suserMail,uniqueEmail,pwdformat,isAnonymous,isLockedOut,isApproved);
			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider CreateProfileForUser portalID: {0}, username: {1}, ex:{2} ", 
                        new object[] { PortalID, username, ex }),SecurityTraceSwitch.Sw.Info);
				throw;
			}
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider CreateProfileForUser UserName : {0}, CrmCustomerId: '{1}'", username, CrmCustomerId),SecurityTraceSwitch.Sw.Info);
			return CrmCustomerId;
		}


		//
		// ProfileProvider.DeleteProfiles(ProfileInfoCollection)
		//

		public override int DeleteProfiles(ProfileInfoCollection profiles)
		{
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider DeleteProfiles begin Profiles.count : {0}", profiles.Count),SecurityTraceSwitch.Sw.Info);
			int deleteCount			= 0;
			SqlConnection conn		= new SqlConnection(connectionString);
			SqlTransaction tran		= null;
			try
			{
				conn.Open();
				tran = conn.BeginTransaction();
				foreach (ProfileInfo p in profiles)
				{
					if (DeleteProfile(p.UserName, conn, tran))
						deleteCount++;
				}
				tran.Commit();
			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceProfileProvider DeleteProfiles ex:{0}", ex),SecurityTraceSwitch.Sw.Info);
				try
				{
					tran.Rollback();
				}
				catch (Exception ex2)
				{
					if ( SecurityTraceSwitch.Sw.TraceError )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceProfileProvider DeleteProfiles Rollback ex:{0}", ex2),SecurityTraceSwitch.Sw.Info);
				}
				throw ex;

			}
			finally
			{
				conn.Close();
			}
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider DeleteProfiles begin Profiles.count : {0}/{1}", deleteCount, profiles.Count),SecurityTraceSwitch.Sw.Info);
			return deleteCount;
		}


		//
		// ProfileProvider.DeleteProfiles(string[])
		//

		public override int DeleteProfiles(string[] usernames)
		{
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider DeleteProfiles begin usernames.GetLength : {0}", usernames.Length),SecurityTraceSwitch.Sw.Info);
			int deleteCount = 0;

			SqlConnection conn = new SqlConnection(connectionString);
			SqlTransaction tran = null;

			try
			{
				conn.Open();
				tran = conn.BeginTransaction();

				foreach (string user in usernames)
				{
					if (DeleteProfile(user, conn, tran))
						deleteCount++;
				}

				tran.Commit();
			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceProfileProvider DeleteProfiles2 ex:{0}", ex),SecurityTraceSwitch.Sw.Info);
				try
				{
					tran.Rollback();
				}
				catch (Exception ex2)
				{
					if ( SecurityTraceSwitch.Sw.TraceError )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceProfileProvider DeleteProfiles2 Rollback ex:{0}", ex2),SecurityTraceSwitch.Sw.Info);
				}
				throw ex;
			}
			finally
			{
				conn.Close();
			}
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider DeleteProfiles begin Profiles.count : {0}/{1}", deleteCount, usernames.Length),SecurityTraceSwitch.Sw.Info);
			return deleteCount;
		}



		//
		// ProfileProvider.DeleteInactiveProfiles
		//

		public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
		{
			if ( SecurityTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]AddonNiceProfileProvider DeleteInactiveProfiles begin userInactiveSinceDate: {0}", userInactiveSinceDate),SecurityTraceSwitch.Sw.Info);

			SqlConnection conn		= new SqlConnection(connectionString);
			SqlCommand cmd			= new SqlCommand("dbo.adn_GetAllAddonNiceInactiveProfile", conn);
			cmd.CommandType			= CommandType.StoredProcedure;

			cmd.Parameters.Add("@PortalID", SqlDbType.Int).Value = PortalID;
			cmd.Parameters.Add("@LastActivityDate", SqlDbType.DateTime).Value = userInactiveSinceDate.ToUniversalTime();

			switch (authenticationOption)
			{
				default:
				case ProfileAuthenticationOption.Anonymous:
					cmd.Parameters.Add("@IsAnonymous", SqlDbType.Bit).Value = true;
					break;

				case ProfileAuthenticationOption.Authenticated:
					cmd.Parameters.Add("@IsAnonymous", SqlDbType.Bit).Value = false;
					break;
			}

			SqlDataReader reader	= null;
			StringBuilder sb		= new StringBuilder();

			try
			{
				conn.Open();
				reader				= cmd.ExecuteReader(CommandBehavior.CloseConnection);

				while (reader.Read())
					sb.AppendFormat("{0},", reader.GetString(0));
			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceProfileProvider DeleteInactiveProfiles ex:{0}", ex),SecurityTraceSwitch.Sw.Info);
				throw;
			}
			finally
			{
				if (reader != null)
					reader.Close();
			}
			string usernames		= sb.ToString();
			// Remove trailing comma.
			if (usernames.Length > 0)
				usernames			= usernames.Substring(0, usernames.Length - 1);
			// Delete profiles.
			return DeleteProfiles(usernames.Split(','));
		}


		//
		// DeleteProfile
		// Deletes profile data from the database for the 
		// specified user name.
		//

		private bool DeleteProfile(string username, SqlConnection conn, SqlTransaction tran)
		{
			// Check for valid user name.
			if (string.IsNullOrEmpty(username))
				throw new ArgumentNullException("User name cannot be null.");
			if (username.Length > 255)
				throw new ArgumentException("User name exceeds 255 characters.");
			if (username.IndexOf(",") > 0)
				throw new ArgumentException("User name cannot contain a comma (,).");


			DynEntity dynEnt	= GetCrmCustomerId(username);

			SqlCommand cmd		= new SqlCommand("dbo.adn_DeleteAddonNiceProfile", conn);
			cmd.CommandType		= CommandType.StoredProcedure;

			cmd.Parameters.Add("@PortalID", SqlDbType.Int).Value					= PortalID;
			//cmd.Parameters.Add("@CrmTypeCode", SqlDbType.Int).Value					= typeCode;
			cmd.Parameters.Add("@CrmCustomerId", SqlDbType.UniqueIdentifier).Value	= dynEnt.PrimaryKeyGuidValue;

			cmd.Transaction		= tran;

			int numDeleted		= 0;

			// Exceptions will be caught by the calling method.
			numDeleted			+= cmd.ExecuteNonQuery();

			if (numDeleted == 0)
				return false;
			return true;
		}


		//
		// ProfileProvider.FindProfilesByUserName
		//

		public override ProfileInfoCollection FindProfilesByUserName(
		  ProfileAuthenticationOption authenticationOption,
		  string usernameToMatch,
		  int pageIndex,int pageSize,out int totalRecords)
		{
			CheckParameters(pageIndex, pageSize);
			return GetProfileInfo(authenticationOption, usernameToMatch,null, pageIndex, pageSize, out totalRecords);
		}


		//
		// ProfileProvider.FindInactiveProfilesByUserName
		//

		public override ProfileInfoCollection FindInactiveProfilesByUserName(
		  ProfileAuthenticationOption authenticationOption,
		  string usernameToMatch,
		  DateTime userInactiveSinceDate,
		  int pageIndex,int pageSize,out int totalRecords)
		{
			CheckParameters(pageIndex, pageSize);
			return GetProfileInfo(authenticationOption, usernameToMatch, userInactiveSinceDate,pageIndex, pageSize, out totalRecords);
		}


		//
		// ProfileProvider.GetAllProfiles
		//

		public override ProfileInfoCollection GetAllProfiles(
		  ProfileAuthenticationOption authenticationOption,
		  int pageIndex, int pageSize,out int totalRecords)
		{
			CheckParameters(pageIndex, pageSize);
			return GetProfileInfo(authenticationOption, null, null,pageIndex, pageSize, out totalRecords);
		}


		//
		// ProfileProvider.GetAllInactiveProfiles
		//

		public override ProfileInfoCollection GetAllInactiveProfiles(
		  ProfileAuthenticationOption authenticationOption,
		  DateTime userInactiveSinceDate,
		  int pageIndex,int pageSize, out int totalRecords)
		{
			CheckParameters(pageIndex, pageSize);
			return GetProfileInfo(authenticationOption, null, userInactiveSinceDate,pageIndex, pageSize, out totalRecords);
		}



		//
		// ProfileProvider.GetNumberOfInactiveProfiles
		//

		public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption,DateTime userInactiveSinceDate)
		{
			int inactiveProfiles			=	0;
			GetProfileInfo(authenticationOption, null, userInactiveSinceDate,0, 0, out inactiveProfiles);
			return inactiveProfiles;
		}



		//
		// CheckParameters
		// Verifies input parameters for page size and page index. 
		// Called by GetAllProfiles, GetAllInactiveProfiles, 
		// FindProfilesByUserName, and FindInactiveProfilesByUserName.
		//

		private void CheckParameters(int pageIndex, int pageSize)
		{
			if (pageIndex < 0)
				throw new ArgumentException("Page index must 0 or greater.");
			if (pageSize < 1)
				throw new ArgumentException("Page size must be greater than 0.");
		}


		//
		// GetProfileInfo
		// Retrieves a count of profiles and creates a 
		// ProfileInfoCollection from the profile data in the 
		// database. Called by GetAllProfiles, GetAllInactiveProfiles,
		// FindProfilesByUserName, FindInactiveProfilesByUserName, 
		// and GetNumberOfInactiveProfiles.
		// Specifying a pageIndex of 0 retrieves a count of the results only.
		//

		private ProfileInfoCollection GetProfileInfo( ProfileAuthenticationOption authenticationOption,
		  string usernameToMatch,object userInactiveSinceDate,
		  int pageIndex,int pageSize,out int totalRecords)
		{
			// If searching for a user name to match, add the command text and parameters.
			string usernameTM	=	"*";
			if (usernameToMatch != null)
				usernameTM			= usernameToMatch;
			// If searching for inactive profiles, 
			DateTime userInactiveSince	= DateTime.UtcNow;
			if (userInactiveSinceDate != null)
				userInactiveSince		= ((DateTime)userInactiveSinceDate).ToUniversalTime();
			// If searching for a anonymous or authenticated profiles,    
			/*bool IsAnonymous	=	 false;
			switch (authenticationOption)
			{
				case ProfileAuthenticationOption.Anonymous:
					IsAnonymous		= true;
					break;
				default:
				case ProfileAuthenticationOption.Authenticated:
					IsAnonymous		= false;
					break;
			}*/
			// Get the data.
			SqlDataReader reader	= null;
			totalRecords			= 0;
			ProfileInfoCollection profiles = new ProfileInfoCollection();
			try
			{
				//reader = new AddonNiceUserDB().GetAllAddonNicePortalProfileLike(PortalID,usernameTM,userInactiveSince,IsAnonymous,pageIndex,pageSize);
				while (reader != null && reader.Read())
				{
					// Get the pro<file count.
					totalRecords	= reader.GetInt32(0);
				}
				// No profiles found.
				if (totalRecords <= 0 || pageSize == 0)
				{
					return profiles;
				}

				reader.NextResult();
				int counter			= 0;
				int startIndex		= pageSize * (pageIndex - 1);
				int endIndex		= startIndex + pageSize - 1;

				while (reader.Read())
				{
					if (counter >= startIndex)
					{
						ProfileInfo p = GetProfileInfoFromReader(reader);
						profiles.Add(p);
					}

					if (counter >= endIndex)
						break;
					counter++;
				}

			}
			catch (Exception ex)
			{
				if ( SecurityTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]AddonNiceProfileProvider GetProfileInfo ex:{0}", ex),SecurityTraceSwitch.Sw.Info);
				throw;
			}
			finally
			{
				if (reader != null)
					reader.Close();
			}
			return profiles;
		}

		//
		// GetProfileInfoFromReader
		//  Takes the current row from the SqlDataReader
		// and populates a ProfileInfo object from the values. 
		//
		private ProfileInfo GetProfileInfoFromReader(SqlDataReader reader)
		{
			string username				= (string)reader["ProfileName"];
			DateTime lastActivityDate	= (DateTime)reader["ProfileLastActivityDate"];
			DateTime lastUpdatedDate	= (DateTime)reader["ProfileLastUpdatedDate"];
			bool isAnonymous			= bool.Parse(reader["ProfileIsAnonymous"].ToString());

			// ProfileInfo.Size not currently implemented.
			return new ProfileInfo(username, isAnonymous, lastActivityDate, lastUpdatedDate, 0);
		}
	}
}
